/**************************************************************************//**
 * @item     CosyOS-III Config
 * @file     syscfg.h
 * @brief    OS Config File
 * @author   迟凯峰
 * @version  V1.2.6
 * @date     2025.05.08
 ******************************************************************************/

#ifndef __SYSCFG_H
#define __SYSCFG_H

///////////////////////////////////////////////////////////////////////////////

          //*** <<< Use Configuration Wizard in Context Menu >>> ***//

///////////////////////////////////////////////////////////////////////////////
// <h> 系统配置
// <i> 系统配置

// <o> MCU内核
// <1=> 8051 <2=> 80251 <3=> Cortex-M
// <i> 告知CosyOS您的MCU内核，CosyOS将自动包含相匹配的MCU配置文件和PORT文件。
#define __SYSCFG_MCUCORE                 3

// <s> 标准头文件
// <i> 定义与您的MCU相匹配的标准头文件，您的c文件中不必再包含此文件。
// <i> 注意：在文本编辑界面中定义时，外层应添加双引号，如："stm32f4xx.h"。
// <i> 如果使用STM32CubeMX生成代码并生成main函数，此处定义为"main.h"即可。
#define SYSCFG_STANDARDHEAD              "stm32f4xx.h"

// <o> 系统滴答周期（us）
// <i> 告知CosyOS系统滴答定时器的溢出时间，单位为微秒。
// <i> 是CosyOS软件定时器，延时、超时、定时等操作的基本时间。
// <i> 可开启系统滴答时间统计功能，您的设定值应远大于统计值。
#define SYSCFG_SYSTICK_CYCLE             1000

// <q> 内核锁嵌套
// <i> 内核锁是否支持嵌套调用？
// <i> 通常您可能不会用到内核锁，即使偶尔使用也应是极简的代码、一般不会嵌套调用。
#define SYSCFG_KERNELLOCKNESTING         0

// <q> 安全运行时
// <i> 是否启用安全运行时？
// <i> 安全运行时是CosyOS的安全关键技术之一，可防止某任务长期独占或超时使用处理器。
#define SYSCFG_SAFERUNTIME               0

// <q> 低功耗模式
// <i> 是否启用低功耗模式？
// <i> 如果开启该选项，CosyOS会在系统空闲任务中进入低功耗模式。
// <i> 低功耗模式通常为空闲模式、睡眠模式，可被中断唤醒，但未必所有中断都能唤醒。
// <i> 您也可不启用该功能，并自行配置自己的低功耗，在 idle_hook 中。
#define SYSCFG_LOWPOWERMODE              0

// </h>
///////////////////////////////////////////////////////////////////////////////
// <e> DEBUG配置
// <i> 是否启用DEBUG？
// <i> DEBUG包括命令行与任务管理器，启用DEBUG后，CosyOS会自动创建两个系统任务
// <i> 来实现相关功能，它们分别是：
// <i> 系统调试器：Debugger [maxpri]
// <i> 任务管理器：Taskmgr [maxpri-1]
#define SYSCFG_DEBUGGING                 0

#if SYSCFG_DEBUGGING == 1

// <o> 任务名称最大长度
// <i> 取值范围：<10-255>
// <i> 任务名称应尽量简短，不可过长，因为它会对总的flash和内存占用有着一定影响。
#define SYSCFG_TASKNAMELEN_MAX           10

// <h> 任务管理器监控选项
// <i> 任务管理器监控选项

// <q> PSV-FIFO监控
// <i> 是否开启PendSV_FIFO监控？
// <i> 开启后，系统将自动监控PendSV_FIFO的实际最大占用深度，并通过任务管理器输出，输出格式为：历史最大值/设置值。
// <i> 建议在调试阶段开启此项功能，正式的产品可禁用以提高性能。
#define SYSCFG_PENDSVFIFO_MONITOR        1

// <q> 任务pc值监控
// <i> 是否启用任务pc值监控？
// <i> 当任务管理器被调度运行时，被切换的任务入栈的PC值。
// <i> 当有任务出现代码运行卡死或死循环时，此功能可用来帮助用户锁定具体位置，以便查找BUG。注意，pc值为下一条汇编指令的地址。
// <i> 建议在调试阶段开启此项功能，正式的产品可禁用以提高性能。
// <i> 某任务出现代码运行卡死或死循环的表现：任务始终为就绪状态，且占用较高的CPU使用率，比它优先级低的任务一直都没有机会运行。
#define SYSCFG_TASKPC_MONITOR            1

// <q> 运行时间统计
// <i> 是否启用运行时间统计？
#define SYSCFG_RUNTIME_COUNT             1

// <q> 滴答时间统计
// <i> 是否启用系统滴答时间统计？
// <i> 统计系统滴答定时器中断，在每个系统滴答周期运行时间的平均值。
// <i> 建议在调试阶段开启此项功能，正式的产品可禁用以提高性能。
#define SYSCFG_SYSTICKTIME_COUNT         1

// <q> 当前时间显示
// <i> 是否显示当前时间？
#define SYSCFG_RTC_SHOW                  0

// </h>
#endif

// <q> 开机自动启动任务管理器
// <i> 设备开机后，是否自动启动任务管理器？
#define SYSCFG_TASKMGR_AUTOSTART         1

// <o> 任务管理器默认更新速度
// <500=> 快速（500毫秒）<1000=> 中速（1秒）<2000=> 慢速（2秒）
// <i> 任务管理器默认更新速度
#define SYSCFG_TASKMGR_UPSPEED           1000

// <q> DEBUG钩子是否传参数据包长度给用户？
// <i> DEBUG发送的数据均为字符串，且带有字符串尾'\0'，如果用户需要获取数据包长度，可开启该选项。
#define SYSCFG_DEBUG_SENDLEN             0

// </e>
///////////////////////////////////////////////////////////////////////////////
// <h> 系统任务配置
// <i> 系统任务配置

// <o> Debugger-StackSize
// <i> 系统调试器的任务栈大小，单位为字节数（Bytes）。
#define SYSCFG_STACKSIZE_DEBUGGER        128

// <o> Taskmgr-StackSize
// <i> 任务管理器的任务栈大小，单位为字节数（Bytes）。
#define SYSCFG_STACKSIZE_TASKMGR         128

// <o> Starter-StackSize
// <i> 任务启动器的任务栈大小，单位为字节数（Bytes）。
#define SYSCFG_STACKSIZE_STARTER         128

// <o> Sysidle-StackSize
// <i> 系统空闲任务的任务栈大小，单位为字节数（Bytes）。
#define SYSCFG_STACKSIZE_SYSIDLE         128

// <o> 任务栈重分配增量
// <i> 当任务栈模式为MSP模式、任务为动态创建时，CosyOS将自动启用任务栈重分配机制，以抵御任务栈溢出的风险。
// <i> 通过合理的配置一个重分配增量，可有效降低重分配的次数，减少内存碎片。
// <i> 此值的设置适当就好，不建议过大或过小。
#define SYSCFG_TASKSTACK_REALLOCINC      32

// <o> Starter-创建模式
// <0=> 静态创建 <1=> 动态创建
// <i> 一般情况下，推荐采用动态创建，Starter删除自身后，内存可被回收；
// <i> 但用户千万不要忘记配置足够大的内存池或HEAP。
#define __SYSCFG_STARTERCREATE           0

// </h>
///////////////////////////////////////////////////////////////////////////////
// <h> 全局任务配置
// <i> 全局任务配置

// <o> 任务PICK位图
// <1=> 128字节 <2=> 256字节
// <i> 128字节PICK位图占用128字节常量内存；
// <i> 256字节PICK位图占用256字节常量内存；
// <i> 256字节PICK位图的任务调度性能优于128字节PICK位图。
#define SYSCFG_TASKPICKBITMAP            1

// <o> 任务优先级总数
// <i> CosyOS的任务优先级，数值越大优先级越高，数值越小优先级越低，最低优先级固定为0级。
// <i> 如任务优先级总数为8，则最高优先级为7级，最低优先级为0级。
// <i> 如果未启用DEBUG接口，系统会占用3级优先级，包括最高两级和最低一级；
// <i> 如果启用了DEBUG接口，系统会占用5级优先级，包括最高四级和最低一级；
// <i> 设置任务优先级总数，应有分组意识，如8级不够用应尽量控制在64级内；如64级不够用，最大可为256；
// <i> 原因是：
// <i> <=8：任务就绪表为零级位图；
// <i> <=64：任务就绪表为一级位图；
// <i> <=256：任务就绪表为二级位图。
#define SYSCFG_TASKPRIORITY              16

// <o> 相同优先级任务调度算法
// <0=> 无调度 <1=> 协作式调度 <2=> 时间片轮转调度
// <i> 对于 CosyOS 来说，不同优先级的任务，永远都实行抢占式调度；
// <i> 而相同优先级的任务，则分为无调度、协作式调度、时间片轮转调度。
// <i> 无调度，是指不支持相同优先级的任务调度，每个任务的优先级都必须不同。
// <i> 协作式调度，要求任务必须主动放弃处理器使用权（阻塞或挂起等方式），才能切换至下一个相同优先级的任务运行。
// <i> 协作式调度，在性能上会高于时间片轮转调度，而且更节约内存。
// <i> 协作式调度，用户不能创建自己的空闲任务。
// <i> 在未经深思熟虑时，可优先选择时间片轮转调度，以保证相同优先级任务的平等运行机会。
#define SYSCFG_SAMEPRISCHEDULE           2

// <h> 时间片模式
// <i> 当相同优先级任务调度算法选择为时间片轮转调度时，应定义此项。
// <i> CosyOS有三种时间片的定义模式，全局时间片、算法时间片、自定义时间片，您只能选其一。
// <i> 全局时间片，所有任务采用相同的时间片。
// <i> 算法时间片，不同优先级的任务，时间片不同，采用一个算法公式来描述。
// <i> 自定义时间片，不同优先级的任务，时间片不同，用户自定义各优先级的时间片。
// <i> 全局时间片，简单高效，时间片轮转调度性能为最佳；算法时间片、自定义时间片，可实现不同优先级的、精细的时间片控制。
// <i> 时间片的取值范围：<1-65535>，单位为滴答周期。

// <e> 全局时间片
// <i> 是否启用全局时间片？
#define __SYSCFG_GLOBALTIMESHARING       1

// <o> 时间片时间
// <i> 时间片时间
#define SYSCFG_GLOBALTIMESHARING         100
// </e>

// <e> 算法时间片
// <i> 是否启用算法时间片？
#define __SYSCFG_ALGORITHMTIMESHARING    0

// <o> 时间片算法公式
// <i> 时间片 = f(pri)，pri为任务优先级。
// <i> 应在文本编辑界面中定义，默认定义为示例，任务优先级总数为16。
#define SYSCFG_ALGORITHMTIMESHARING(pri) ((16 - pri) * 5)
// </e>

// <e> 自定义时间片
// <i> 是否启用自定义时间片？
#define __SYSCFG_CUSTOMTIMESHARING       0

// <o> 时间片数组
// <i> 从优先级0级开始，逐个写出各优先级的时间片并用逗号间隔。
// <i> 应在文本编辑界面中定义，默认定义为示例，任务优先级总数为16。
#define SYSCFG_CUSTOMTIMESHARING         100,90,80,70,60,50,40,30,20,10,7,5,4,3,2,1

// <o> 时间片最大值
// <i> 时间片最大值
#define SYSCFG_TIMESHARING_MAX           255
// </e>
// </h>

// <o> 在线用户任务总数
// <i> 当相同优先级任务调度算法未选择无调度时，应定义此项。
// <i> 仅指启动并加入到任务队列的用户任务总数，不包括未启动的任务和系统任务。
// <i> 此项参数应大于等于实际的数量，但不可小于。
#define SYSCFG_USERTASKTOTAL             16

// <o> 延时定时器位数/延时超时最大有效值（系统滴答周期数）
// <8=> 8位/254 <16=> 16位/65,534 <32=> 32位/4,294,967,294 <64=> 64位
// <i> 如果您的MCU内核为8051，此项建议尽量配置为低位（8位/16位），这将使大部分任务服务的执行效率提升约10%。
#define SYSCFG_DELAYBITS                 32

// </h>
///////////////////////////////////////////////////////////////////////////////
// <h> 定时中断/查询设置
// <i> 定时中断/查询设置

// <o> 用户定时中断总数
// <i> 取值范围：<0-64>
// <i> 用户创建的定时中断任务/钩子总数。
// <i> 此项参数应等于实际的数量，既不能大于也不能小于。
// <i> 如果定义数量大于实际数量，会引起编译器警告，否则不会有任何提示。
#define SYSCFG_USERTIMINTTOTAL           0

// <o> 用户定时查询总数
// <i> 取值范围：<0-64>
// <i> 用户创建的定时查询任务/钩子总数。
// <i> 此项参数应等于实际的数量，既不能大于也不能小于。
// <i> 如果定义数量大于实际数量，会引起编译器警告，否则不会有任何提示。
#define SYSCFG_USERTIMQRYTOTAL           0

// <o> 用户定时查询初始化状态
// <0=> 停止状态 <1=> 查询状态
// <i> 停止状态：用户的定时查询，在初始化后为停止状态，不能计数也不能查询用户定义的事件。
// <i> 查询状态：用户的定时查询，在初始化后为查询状态，系统已经开始查询用户定义的事件了。
#define SYSCFG_USERTIMQRYINIT            1

// <o> 定时中断定时器位数/定时最大有效值（系统滴答周期数）
// <8=> 8位/254 <16=> 16位/65,534 <32=> 32位/4,294,967,294 <64=> 64位
// <i> 如果您的MCU内核为8051，此项建议尽量配置为低位，以提高性能。
#define SYSCFG_TIMINTBITS                32

// <o> 定时查询定时器位数/定时最大有效值（系统滴答周期数）
// <8=> 8位/254 <16=> 16位/65,534 <32=> 32位/4,294,967,294 <64=> 64位
// <i> 如果您的MCU内核为8051，此项建议尽量配置为低位，以提高性能。
#define SYSCFG_TIMQRYBITS                32

// </h>
///////////////////////////////////////////////////////////////////////////////
// <h> 钩子函数设置
// <i> 钩子函数设置

// <q> 空闲钩子
// <i> 是否启用空闲钩子？
#define SYSCFG_IDLEHOOK                  0

// <q> 滴答钩子
// <i> 是否启用滴答钩子？
#define SYSCFG_TICKHOOK                  0

// <q> 挂起服务钩子
// <i> 是否启用挂起服务钩子？
#define SYSCFG_PENDSVHOOK                0

// <q> 副本钩子
// <i> 是否启用副本钩子？
#define SYSCFG_COPYHOOK                  0

// </h>
///////////////////////////////////////////////////////////////////////////////
// <h> 线程通信设置
// <i> 线程通信设置

// <e> 互斥信号量
// <i> 是否启用互斥信号量？
#define SYSCFG_MUTEX                     1

// <o> 天花板基本优先级
// <i> 当相同优先级任务调度算法选择无调度时，应定义此项。
// <i> 此时，互斥信号量将采用优先级天花板机制，来抑制优先级反转的发生。
// <i> CosyOS的优先级天花板有别于传统RTOS，该天花板为一个连续的任务优先级，
// <i> 天花板优先级的数量，取决于您在任务中嵌套获取不同互斥量的最大深度。
// <i> 所有天花板优先级都应做为保留，所有任务都不应该主动占用它们。
// <i> 您应在此定义天花板优先级的最低级。
// <i> 示例：
// <i> 任务优先级数 = 64，其中[63~61]被系统占用，[60~56]被您的高优先级任务占用（这些任务都不可以再使用互斥量）；
// <i> 您在任务中嵌套获取不同互斥量的最大深度 = 3；
// <i> =>
// <i> 天花板基本优先级 = 56-3 = 53，[53~55]为天花板优先级，您不可擅自使用它们。
#define SYSCFG_BASEPRI_CEILING           53
// </e>

// <q> 二值信号量
// <i> 是否启用二值信号量？
#define SYSCFG_BINARY                    1

// <e> 计数信号量
// <i> 是否启用计数信号量？
#define SYSCFG_SEMAPHORE                 1

// <o> 计数信号量位数/最大值
// <8=> 8位/255 <16=> 16位/65,535 <32=> 32位/4,294,967,295 <64=> 64位
// <i> 如果您的MCU内核为8051，此项建议尽量配置为低位，以提高性能。
#define SYSCFG_SEMAPHOREBITS             32
// </e>

// <q> 事件标志组
// <i> 是否启用事件标志组？
#define SYSCFG_FLAGGROUP                 1

// <q> 飞信
// <i> 是否启用飞信？
#define SYSCFG_FETION                    1

// <q> 消息邮箱
// <i> 是否启用消息邮箱？
#define SYSCFG_MAILBOX                   1

// <q> 消息队列
// <i> 是否启用消息队列？
#define SYSCFG_MSGQUEUE                  1

// </h>
///////////////////////////////////////////////////////////////////////////////
// <h> 杂项设置
// <i> 杂项设置

// <q> 用户动态内存分配
// <i> 在任务中是否使用动态内存分配？包括进程内存分配和线程内存分配的相关服务调用。
#define SYSCFG_DYNMEMMGE                 0

// <e> 软件RTC
// <i> 是否启用软件RTC？
#define SYSCFG_SOFTRTC                   0

#if SYSCFG_SOFTRTC == 1
// <q> 中断中获取RTC
// <i> 是否需要在用户中断中获取RTC？关联服务：iGetTime(t)。
#define SYSCFG_GETRTC_INT                0
#endif
// <h> 生产日期

// <o> 年
// <2025=> 2025 <2026=> 2026 <2027=> 2027 <2028=> 2028 <2029=> 2029
// <2030=> 2030 <2031=> 2031 <2032=> 2032 <2033=> 2033 <2034=> 2034 <2035=> 2035 <2036=> 2036 <2037=> 2037 <2038=> 2038 <2039=> 2039
// <2040=> 2040 <2041=> 2041 <2042=> 2042 <2043=> 2043 <2044=> 2044 <2045=> 2045 <2046=> 2046 <2047=> 2047 <2048=> 2048 <2049=> 2049
// <2050=> 2050 <2051=> 2051 <2052=> 2052 <2053=> 2053 <2054=> 2054 <2055=> 2055 <2056=> 2056 <2057=> 2057 <2058=> 2058 <2059=> 2059
// <2060=> 2060 <2061=> 2061 <2062=> 2062 <2063=> 2063 <2064=> 2064 <2065=> 2065 <2066=> 2066 <2067=> 2067 <2068=> 2068 <2069=> 2069
// <2070=> 2070 <2071=> 2071 <2072=> 2072 <2073=> 2073 <2074=> 2074 <2075=> 2075 <2076=> 2076 <2077=> 2077 <2078=> 2078 <2079=> 2079
// <2080=> 2080 <2081=> 2081 <2082=> 2082 <2083=> 2083 <2084=> 2084 <2085=> 2085 <2086=> 2086 <2087=> 2087 <2088=> 2088 <2089=> 2089
// <2090=> 2090 <2091=> 2091 <2092=> 2092 <2093=> 2093 <2094=> 2094 <2095=> 2095 <2096=> 2096 <2097=> 2097 <2098=> 2098 <2099=> 2099
#define __SYSCFG_YEAR                    2025

// <o> 月
// <1=> 1 <2=> 2 <3=> 3 <4=> 4 <5=> 5 <6=> 6 <7=> 7 <8=> 8 <9=> 9 <10=> 10 <11=> 11 <12=> 12
#define __SYSCFG_MONTH                   5

// <o> 日
// <1=> 1 <2=> 2 <3=> 3 <4=> 4 <5=> 5 <6=> 6 <7=> 7 <8=> 8 <9=> 9 <10=> 10
// <11=> 11 <12=> 12 <13=> 13 <14=> 14 <15=> 15 <16=> 16 <17=> 17 <18=> 18 <19=> 19 <20=> 20
// <21=> 21 <22=> 22 <23=> 23 <24=> 24 <25=> 25 <26=> 26 <27=> 27 <28=> 28 <29=> 29 <30=> 30 <31=> 31
#define __SYSCFG_DATE                    8

// <o> 周
// <1=> 一 <2=> 二 <3=> 三 <4=> 四 <5=> 五 <6=> 六 <7=> 日
#define __SYSCFG_WEEK                    4

#define SYSCFG_MANUFACTUREDATE           __SYSCFG_YEAR / 100, __SYSCFG_YEAR % 100, __SYSCFG_MONTH, __SYSCFG_DATE, 0, 0, 0, __SYSCFG_WEEK

// </h>
// </e>

// <o> 创建任务-尾参数功能
// <0=> 遗产模式 <1=> 标准模式 <2=> 兼容模式
// <i> 遗产模式：尾参数无任何功能定义，可随意输入，"任务名称"自动引用任务函数名称。
// <i> 标准模式：尾参数为"任务名称"，需输入任务名称字符串。
// <i> 兼容模式：尾参数如果输入字符串，则为"任务名称"；如果输入0，"任务名称"自动引用任务函数名称。
// <i> 兼容模式，某些编译器不能正常支持。
#define __SYSCFG_CREATETASKCUSTOM        0

// </h>
///////////////////////////////////////////////////////////////////////////////

                //*** <<< end of configuration section >>> ***//

///////////////////////////////////////////////////////////////////////////////

#if   __SYSCFG_MCUCORE == 1
#define SYSCFG_MCUCORE                   8051
#elif __SYSCFG_MCUCORE == 2
#define SYSCFG_MCUCORE                   80251
#elif __SYSCFG_MCUCORE == 3
#define SYSCFG_MCUCORE                   cmx
#endif

#if SYSCFG_DEBUGGING == 0
#define SYSCFG_PENDSVFIFO_MONITOR        0
#define SYSCFG_TASKPC_MONITOR            0
#define SYSCFG_RUNTIME_COUNT             0
#define SYSCFG_SYSTICKTIME_COUNT         0
#define SYSCFG_RTC_SHOW                  0
#elif SYSCFG_RTC_SHOW && !SYSCFG_SOFTRTC
#error 未启用软件RTC，无法显示当前时间！
#endif

#ifdef SYSCFG_TASKNAMELEN_MAX
#if SYSCFG_TASKNAMELEN_MAX < 10 || SYSCFG_TASKNAMELEN_MAX > 255
#error 非法的设置值！
#endif
#endif

#if __SYSCFG_STARTERCREATE == 0
#define SYSCFG_STARTERCREATE u
#else
#define SYSCFG_STARTERCREATE d
#endif

#if   __SYSCFG_GLOBALTIMESHARING == 1 && __SYSCFG_ALGORITHMTIMESHARING == 0 && __SYSCFG_CUSTOMTIMESHARING == 0
#define SYSCFG_TIMESHARINGMODE           0
#elif __SYSCFG_GLOBALTIMESHARING == 0 && __SYSCFG_ALGORITHMTIMESHARING == 1 && __SYSCFG_CUSTOMTIMESHARING == 0
#define SYSCFG_TIMESHARINGMODE           1
#elif __SYSCFG_GLOBALTIMESHARING == 0 && __SYSCFG_ALGORITHMTIMESHARING == 0 && __SYSCFG_CUSTOMTIMESHARING == 1
#define SYSCFG_TIMESHARINGMODE           2
#elif __SYSCFG_GLOBALTIMESHARING == 0 && __SYSCFG_ALGORITHMTIMESHARING == 0 && __SYSCFG_CUSTOMTIMESHARING == 0
#error 时间片模式未定义！
#else
#error 时间片模式重定义！
#endif

#if SYSCFG_USERTIMINTTOTAL > 64
#error 非法的设置值！
#endif

#if SYSCFG_USERTIMQRYTOTAL > 64
#error 非法的设置值！
#endif

#if SYSCFG_SOFTRTC == 0
#define SYSCFG_GETRTC_INT    0
#endif

#if   __SYSCFG_CREATETASKCUSTOM == 0
#define SYSCFG_CREATETASKCUSTOM(name, res) #name
#elif __SYSCFG_CREATETASKCUSTOM == 1
#define SYSCFG_CREATETASKCUSTOM(name, res) res
#elif __SYSCFG_CREATETASKCUSTOM == 2
#define SYSCFG_CREATETASKCUSTOM(name, res) res ? res : #name
#endif



#endif
